﻿using System;
using Aspose.Words;
using System.IO;
using System.Text.RegularExpressions;

namespace I2kCoreEngine
{
    public class WordHandler
    {
        static int _numberOfSearchHits;

        private static DocumentBuilder _docBuilder;

        // A bit of hackery, since there seems not to be a find() method provided
        private static ReplaceAction DontReplace ( object o, ReplaceEvaluatorArgs a )
        {
            _numberOfSearchHits++;
            return ReplaceAction.Skip;
        }

        public static Document[] LoadDocumentsIntoMemory(string[] fileList)
        {
            Document[] documentsArray = new Document[fileList.Length];
            for (int i = 0; i < fileList.Length; i++)
            {
                documentsArray[i] = new Document(fileList[i]);
            }

            return documentsArray;
        }

        public int CountKeywordHits ( Document doc, string[] keywordsArray )
        {
            _numberOfSearchHits = 0;

            StringWriter regexExpression = new StringWriter( );
            regexExpression.Write( "(" );

            if (keywordsArray != null)
            {
                for (int i = 0; i < (keywordsArray.Length - 1); i++)
                {
                    regexExpression.Write( keywordsArray[i] + "|" );
                }

                regexExpression.Write( keywordsArray[keywordsArray.Length - 1] + ")" );
            }

            Regex regexToSearchFor = new Regex( regexExpression.ToString( ), RegexOptions.RightToLeft );

            doc.Range.Replace( regexToSearchFor, DontReplace, true );

            return _numberOfSearchHits;
        }

        public static void PrepareSummaryDocument ( string filePath, ref Document[] documentsArray, string keywordsRegex )
        {
            Regex keyRegex = new Regex( keywordsRegex );
            
            Document targetFile = new Document( );
            Document sourceFile;
            
            NodeCollection docNodeCollection;
            
            _docBuilder = new DocumentBuilder( targetFile );
            SetRtl( true );

            SetAlignment( Alignment.Center );
            _docBuilder.Font.SizeBi = 20;
            _docBuilder.Font.Underline = Underline.Double;
            _docBuilder.Writeln( "דוח ממצאים" );
            _docBuilder.Font.Underline = Underline.None;
            _docBuilder.Writeln( "הופק ב" + DateTime.Now.Date.ToLongDateString( ) + " בשעה " + DateTime.Now.ToShortTimeString( ) + '\n' );
            _docBuilder.Font.SizeBi = 16;

            foreach (Document theDocument in documentsArray)
            {
                sourceFile = new Document( theDocument.OriginalFileName );

                docNodeCollection = sourceFile.GetChildNodes( NodeType.Paragraph, true );

                for (int aParagraph = 0; aParagraph < docNodeCollection.Count; aParagraph++)
                {
                    // Ignore empty paragraphs
                    if (docNodeCollection[aParagraph].GetText( ).Trim( ) == "")
                        continue;

                    string currentParagraph = docNodeCollection[aParagraph].GetText( );

                    MatchCollection theMatches = keyRegex.Matches( currentParagraph );

                    if (theMatches.Count <= 0) continue;

                    // Write the name of the file being analyzed into the report (highlighted)
                    SetRtl(false);
                    SetHighlightColor(HighLight.Lightgreen);
                    SetAlignment(Alignment.Center);
                    _docBuilder.Writeln(theDocument.OriginalFileName + '\n');
                    SetHighlightColor(HighLight.None);
                    SetAlignment(Alignment.Right);
                    SetRtl(true);

                    int placeInString = 0;
                    for (int currentMatch = 0; currentMatch < theMatches.Count; currentMatch++)
                    {
                        SetRtl( true );
                        SetHighlightColor( HighLight.None );
                        _docBuilder.Write(currentParagraph.Substring(placeInString, theMatches[currentMatch].Index - placeInString));
                            
                        placeInString = theMatches[currentMatch].Index;
                            
                        // Set highlighting color here
                        SetHighlightColor( HighLight.Yellow );
                        _docBuilder.Write( currentParagraph.Substring( placeInString, theMatches[currentMatch].Length) );
                        placeInString += theMatches[currentMatch].Length;
                        SetHighlightColor( HighLight.None );
                    }

                    _docBuilder.Writeln( currentParagraph.Substring( placeInString, currentParagraph.Length - placeInString) + '\n' );
                }
            }

            targetFile.Save( filePath );
        }

        #region Helper Enums and Methods
        // Set Right-To-Left writing ON or OFF
        private static void SetRtl ( Boolean isRtl )
        {
            _docBuilder.Font.Bidi = isRtl;
        }

        private enum HighLight
        {
            Yellow,
            Lightgreen,
            None
        }

        private enum Alignment
        {
            Right,
            Center,
            Left
        }

        private static void SetHighlightColor ( HighLight chosenHighlight )
        {
            if (chosenHighlight == HighLight.Yellow)
                _docBuilder.Font.HighlightColor = System.Drawing.Color.Yellow;
            if (chosenHighlight == HighLight.Lightgreen)
                _docBuilder.Font.HighlightColor = System.Drawing.Color.Chartreuse;
            if (chosenHighlight == HighLight.None)
                _docBuilder.Font.HighlightColor = System.Drawing.Color.White;
        }

        private static void SetAlignment ( Alignment chosenAlignment )
        {
            if (chosenAlignment == Alignment.Right)
                _docBuilder.ParagraphFormat.Alignment = ParagraphAlignment.Right;
            if (chosenAlignment == Alignment.Center)
                _docBuilder.ParagraphFormat.Alignment = ParagraphAlignment.Center;
            if (chosenAlignment == Alignment.Left)
                _docBuilder.ParagraphFormat.Alignment = ParagraphAlignment.Left;
        }

        #endregion

        // Unit Testing
        public static void TestSummary ( )
        {
            string[] theFiles = Utilities.FindFilesInDirectory(@"C:\Temp\NetanyaProtocols\", Utilities.FileTypes.Word, true);
            Document[] theDocuments = LoadDocumentsIntoMemory( theFiles );
            //PrepareSummaryDocument(@"c:\Temp\Summary.doc", ref TheDocuments, @"(\bשלום\b|\bמדינה\b)");
            PrepareSummaryDocument( @"c:\Temp\Summary.doc", ref theDocuments, @"(שחיתות|כספי הציבור)" );
        }
    }
}